package br.gendi.dialog;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;

import au.id.jericho.lib.html.Source;

public class VisualizadorTabelas implements IVisualizador {

	private Shell sShell = null;  //  @jve:decl-index=0:visual-constraint="10,10"
	private StyledText styledText = null;
	private Table table = null;
	private SashForm sashForm = null;
	private Composite composite = null;
	private Composite composite1 = null;
	private TabFolder tabFolder = null;
	private HashMap<String, String> sourcesTXT = null;
	private HashMap<String, String> sourcesTabela = null;

	private void createSashForm() {
		sashForm = new SashForm(tabFolder, SWT.NONE);
		createComposite();
		createComposite1();
	}

	private void createComposite() {
		GridData gridData = new GridData();
		gridData.horizontalAlignment = GridData.FILL;
		gridData.grabExcessHorizontalSpace = true;
		gridData.grabExcessVerticalSpace = true;
		gridData.verticalAlignment = GridData.FILL;
		composite = new Composite(sashForm, SWT.NONE);
		composite.setLayout(new GridLayout());
		composite.setLayoutData(gridData);
	}

	private void createComposite1() {
		composite1 = new Composite(sashForm, SWT.NONE);
		composite1.setLayout(new FillLayout());
	}

	private void createTabFolder() {
		tabFolder = new TabFolder(sShell, SWT.NONE);
		createSashForm();
	}

	
	public VisualizadorTabelas() {
		super();
		if (sourcesTXT == null)
			sourcesTXT = new HashMap<String, String>();
		if (sourcesTabela == null)
			sourcesTabela = new HashMap<String, String>();
		createSShell();
	}

	private void createSShell() {
		FillLayout fillLayout = new FillLayout();
		fillLayout.spacing = 2;
		fillLayout.marginWidth = 2;
		fillLayout.type = org.eclipse.swt.SWT.VERTICAL;
		fillLayout.marginHeight = 2;
		sShell = new Shell(SWT.SHELL_TRIM);
		sShell.setText("Resultados");
		sShell.setLayout(fillLayout);
		createTabFolder();
		
		ImageData isLarge = br.gendi.rcp.Activator.getImageDescriptor("/icons/mainicon32.png").getImageData();
		ImageData isSmall = br.gendi.rcp.Activator.getImageDescriptor("/icons/mainicon16.png").getImageData();

		Image large = new Image(sShell.getDisplay(), isLarge);
		Image small = new Image(sShell.getDisplay(), isSmall);

		sShell.setImages(new Image[] {small, large});
		
		sShell.setSize(800,600);
Rectangle pDisplayBounds = sShell.getDisplay().getBounds();
		
        // Set Width and Height(doesn't matter value)
		int nMinWidth = pDisplayBounds.width  / 2;
		int nMinHeight = pDisplayBounds.height / 2;

         // This formulae calculate the shell's Left ant Top
		int nLeft = (pDisplayBounds.width - nMinWidth) / 2;
		int nTop = (pDisplayBounds.height - nMinHeight) / 2;
              
          // Set shell bounds,
		sShell.setBounds(nLeft, nTop, nMinWidth, nMinHeight);
		/*
		try {
			gerarTabela("data/epij.txt.html");
			gerarTabela("data/rankpep.html");
			gerarTabela("data/syfpeithi.html");
			gerarTabela("data/hlabind.html");
		} catch (Exception e) {
			e.printStackTrace();
		}
		 */
	}

	public void adicionar( final String nome, final String html) throws Exception {
		createSashForm();

		GridData gridData2 = new GridData();
		gridData2.horizontalAlignment = GridData.BEGINNING;
		gridData2.grabExcessHorizontalSpace = true;
		gridData2.verticalAlignment = GridData.BEGINNING;
		GridData gridData1 = new GridData();
		gridData1.horizontalAlignment = GridData.FILL;
		gridData1.grabExcessHorizontalSpace = true;
		gridData1.grabExcessVerticalSpace = true;
		gridData1.verticalAlignment = GridData.FILL;
		GridData gridData = new GridData();
		gridData.horizontalAlignment = GridData.FILL;
		gridData.grabExcessHorizontalSpace = true;
		gridData.grabExcessVerticalSpace = true;
		gridData.verticalAlignment = GridData.FILL;

		Button button = new Button(composite, SWT.NONE);
		button.setLayoutData(gridData2);
		button.setText("Salvar o resultado");
		button.setImage(new Image(sShell.getDisplay(),br.gendi.rcp.Activator.getImageDescriptor("/icons/save.gif").getImageData()));
		button.addSelectionListener(new SelectionListener() {
			@Override
			public void widgetDefaultSelected(SelectionEvent arg0) {

			}
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				
				DirectoryDialog fd = new DirectoryDialog(sShell);
				String path = null;
				path = fd.open();
				if (path != null) {
					
					Iterator<String> keys = sourcesTXT.keySet().iterator();
					String ret = null;
					while (keys.hasNext()) {
						
						ret = keys.next();
						File f = new File(path + File.separator + ret + ".txt");
						if (!f.exists()) {
							try {
								f.createNewFile();
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
						FileWriter fw=null;
						try {
							fw = new FileWriter(f);
							fw.write(sourcesTXT.get(ret));
							fw.flush();
							fw.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}
		});

		table = new Table(composite1, SWT.BORDER | SWT.V_SCROLL | SWT.MULTI);
		table.setHeaderVisible(true);
		table.setLinesVisible(true);

		styledText = new StyledText(composite, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
		styledText.setEditable(true);
		styledText.setLayoutData(gridData1);

		TabItem tabItem = new TabItem(tabFolder, SWT.NONE);
		tabItem.setControl(sashForm);
		tabItem.setText(nome);

		ArrayList<String> l = new ArrayList<String>();
		ArrayList<String> linhasTabela = new ArrayList<String>();
		int maior = 0;
		String tmp = null;
		String[] stringTab = null;
		String tmpTab[] = null;

		Source source=new Source(html);
		String renderedText=source.getRenderer().toString();
		sourcesTXT.put(nome, renderedText);
		String[] linhas = renderedText.split("\n");

		//removendo linhas vazias
		for (int i=0; i< linhas.length; i++) {
			if (linhas[i].trim().length() > 0)
				l.add(linhas[i]);
		}

		//verificando qual a linha com maior numero de \t
		//para ser as linhas que vão para a Table
		for (int i=0; i< l.size(); i++) {
			tmp = l.get(i);
			if (tmp.contains("\t")) {
				stringTab = l.get(i).split("\t");
				if (stringTab.length > maior)
					maior = stringTab.length;
			} 
		}


		//passando as informações nos seus devidos locais.
		for (int i=0; i< l.size(); i++) {
			tmp = l.get(i);
			if (tmp.contains("\t")) {
				stringTab = l.get(i).split("\t");

				if (stringTab.length == maior) {
					linhasTabela.add(tmp);
				} else {
					styledText.setText(styledText.getText()+tmp);
				}
			} else {
				styledText.setText(styledText.getText()+tmp);
			}
		}

		//adicionando as tabelas.
		for (int i=0;i<linhasTabela.size(); i++) {
			tmp = linhasTabela.get(i);
			tmpTab = tmp.split("\t");

			if (i==0) {
				for (int j=0; j<tmpTab.length; j++) {
					TableColumn column = new TableColumn (table, SWT.NONE);
					if (tmpTab[j].contains("\r")) {
						tmpTab[j] = tmpTab[j].replaceAll("\r", "");
					}
					column.setText(tmpTab[j]);
				}
			} else {
				final TableColumn [] columns = table.getColumns ();
				TableItem item = new TableItem (table, SWT.NONE);
				for (int j=0; j<columns.length; j++) {
					if (tmpTab[j].contains("\r")) {
						tmpTab[j] = tmpTab[j].replaceAll("\r", "");
					}
					item.setText (j, tmpTab[j]);
				}
			}
		}
		final TableColumn [] columns = table.getColumns();
		for (int i=0; i<columns.length; i++) 
			columns[i].pack();

Rectangle pDisplayBounds = sShell.getDisplay().getBounds();
		
        // Set Width and Height(doesn't matter value)
		int nMinWidth = pDisplayBounds.width  / 2;
		int nMinHeight = pDisplayBounds.height / 2;

         // This formulae calculate the shell's Left ant Top
		int nLeft = (pDisplayBounds.width - nMinWidth) / 2;
		int nTop = (pDisplayBounds.height - nMinHeight) / 2;
              
          // Set shell bounds,
		sShell.setBounds(nLeft, nTop, nMinWidth, nMinHeight);
		
		if (!sShell.isVisible())
			sShell.open();
	}


	private void gerarTabela(String sourceUrlString ) throws Exception {
		createSashForm();
		table = new Table(composite1, SWT.BORDER | SWT.V_SCROLL | SWT.MULTI);
		table.setHeaderVisible(true);
		table.setLinesVisible(true);

		styledText = new StyledText(composite, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
		styledText.setEditable(true);

		TabItem tabItem = new TabItem(tabFolder, SWT.NONE);
		tabItem.setControl(sashForm);
		tabItem.setText(sourceUrlString);

		ArrayList<String> l = new ArrayList<String>();
		ArrayList<String> linhasTabela = new ArrayList<String>();
		int maior = 0;
		String tmp = null;
		String[] stringTab = null;
		String tmpTab[] = null;

		if (sourceUrlString.indexOf(':')==-1) 
			sourceUrlString="file:"+sourceUrlString;
		Source source=new Source(new URL(sourceUrlString));
		String renderedText=source.getRenderer().toString();
		String[] linhas = renderedText.split("\n");

		//removendo linhas vazias
		for (int i=0; i< linhas.length; i++) {
			if (linhas[i].trim().length() > 0)
				l.add(linhas[i]);
		}

		//verificando qual a linha com maior numero de \t
		//para ser as linhas que vão para a Table
		for (int i=0; i< l.size(); i++) {
			tmp = l.get(i);
			if (tmp.contains("\t")) {
				stringTab = l.get(i).split("\t");
				if (stringTab.length > maior)
					maior = stringTab.length;
			} 
		}


		//passando as informações nos seus devidos locais.
		for (int i=0; i< l.size(); i++) {
			tmp = l.get(i);
			if (tmp.contains("\t")) {
				stringTab = l.get(i).split("\t");

				if (stringTab.length == maior) {
					linhasTabela.add(tmp);
				} else {
					styledText.setText(styledText.getText()+tmp);
				}
			} else {
				styledText.setText(styledText.getText()+tmp);
			}
		}

		//adicionando as tabelas.
		//TODO: adicionar as linhas no hash da tabela para gerar o resultado final.
		for (int i=0;i<linhasTabela.size(); i++) {
			tmp = linhasTabela.get(i);
			tmpTab = tmp.split("\t");

			if (i==0) {
				for (int j=0; j<tmpTab.length; j++) {
					TableColumn column = new TableColumn (table, SWT.NONE);
					if (tmpTab[j].contains("\r")) {
						tmpTab[j] = tmpTab[j].replaceAll("\r", "");
					}
					column.setText(tmpTab[j]);
				}
			} else {
				final TableColumn [] columns = table.getColumns ();
				TableItem item = new TableItem (table, SWT.NONE);
				for (int j=0; j<columns.length; j++) {
					if (tmpTab[j].contains("\r")) {
						tmpTab[j] = tmpTab[j].replaceAll("\r", "");
					}
					item.setText (j, tmpTab[j]);
				}
			}
		}
		final TableColumn [] columns = table.getColumns();
		for (int i=0; i<columns.length; i++) 
			columns[i].pack();

Rectangle pDisplayBounds = sShell.getDisplay().getBounds();
		
        // Set Width and Height(doesn't matter value)
		int nMinWidth = pDisplayBounds.width  / 2;
		int nMinHeight = pDisplayBounds.height / 2;

         // This formulae calculate the shell's Left ant Top
		int nLeft = (pDisplayBounds.width - nMinWidth) / 2;
		int nTop = (pDisplayBounds.height - nMinHeight) / 2;
              
          // Set shell bounds,
		sShell.setBounds(nLeft, nTop, nMinWidth, nMinHeight);
		
		if (!sShell.isVisible())
			sShell.open();
	}
}